#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h> //进程等待相关函数头文件

int main()
{
  //演示 waitpid()
  pid_t id = fork();  //创建子进程
  if(id == 0)
  {
    int time = 9;
    int n = 0;
    while(n < time)
    {
      printf("我是子进程，我已经运行了:%d秒 PID:%d   PPID:%d\n", n + 1, getpid(), getppid());
      sleep(1);
      n++;
    }

    exit(244);  //子进程退出
  }

  int status = 0; //状态
  pid_t ret = 0;
  while(1)
  {

    ret = waitpid(id, &status, WNOHANG); //参数3 设置为非阻塞状态
    
    if(ret == -1)
    {
      printf("进程等待失败！进程不存在！\n");
      break;
    }
    else if(ret == 0)
    { 
      printf("子进程还在运行中！\n");
      printf("我可以干一些其他任务\n");
      sleep(3);
    }
    else
    {
      printf("进程等待成功，子进程已被回收\n");
      //通过 status 判断子进程运行情况
      if(WIFEXITED(status))
      {
        printf("子进程正常退出，退出码：%d\n", WEXITSTATUS(status));
        break;
      }
      else
      {
        printf("子进程异常退出，code dump：%d   退出信号：%d\n", (status >> 7) & 1, (status & 0x7F));
        break;
      }
    }
  }

  return 0;
}

// int main()
// {
//   printf("You can see me");
//   //exit(-1); //退出程序
//   _exit(-1);  //第二个函数
//   return 0;
// }

// int main()
// {
//   while(1)
//   {
//     ;
//   }
//   return 156;
// }

// const char* ps = "This is an Apple";  //全局属性

// int main()
// {
//   pid_t id = fork();
//   if(id == 0)
//   {
//     ps = "This is a Banana"; //改写
//     printf("我是子进程，我认为：%s\n", ps);
//     exit(0);  //子进程退出
//   }

//   wait(0);  //等待子进程退出
//   printf("我是父进程，我认为：%s\n", ps);
//   return 0;
// }

// int main()
// {
//   //创建两个子进程
//   pid_t id1 = fork();
//   if(id1 == 0)
//   {
//     //子进程创建成功，创建孙子进程
//     pid_t id2 = fork();
//     if(id2 == 0)
//     {
//       printf("我是孙子进程，PID:%d   PPID:%d\n", getpid(), getppid());
//       exit(1); //孙子进程运行结束后，退出
//     }

//       wait(0);  //等待孙子进程运行结束
//       printf("我是子进程，PID:%d   PPID:%d\n", getpid(), getppid());
//       exit(1);  //子进程运行结束后，退出
//   }

//   wait(0);  //等待子进程运行结束
//   printf("我是父进程，PID:%d   PPID:%d\n", getpid(), getppid());

//   return 0; //父进程运行结束后，退出
// }
